#!/usr/bin/env python

# Author: Adenilson Cavalcanti
#         Tomaz Noleto
#        Copyright 20-01-2008
# About: Tablet Amora main UI class file
# (more information, visit: http://code.google.com/p/amora

'''
/*  Copyright (C) 2008  Adenilson Cavalcanti <savagobr@yahoo.com>
 *                      Tomaz Noleto <tnoleto@gmail.com>
 *
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; by version 2 of the License.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */
'''


import ecore
import ecore.evas
import edje
import edje.decorators
import evas
import sys
import os
import dbus_discover
import btio
import protocol
import controller

WIDTH_DFL = 800
HEIGHT_DFL = 480
FPS_DFL = 50

APP_TITLE = "Amora Client"
APP_WM_INFO = ("Amora Client", "amora-client")
APP_DATADIR = "/usr/share/amora/"

#The device dictionary (Human readable name, MAC adddress)
devices = {}

#Application objects
device_list = None
view = None
canvas = None
bt_socket = btio.bt()
prot_obj = None
control = None

#D-Bus callback used in discover process
def dbus_device_fill_list(address, name):
	global device_list
	global view
	devices[name] = address
	device_list.device_item((address, name))
	view.swallow_item("list", device_list)
	print u'Found device: ' + name


class AmoraDeviceList(evas.SmartObject):
	def __init__(self, ecanvas, edje_file, coord):
		self.ecanvas = ecanvas
		self.edje_file = edje_file
		self.coord = (coord[0] + 20, coord[1] + 140)

		evas.SmartObject.__init__(self, ecanvas)
		self.dbus_obj = dbus_discover.dbus_bluetooth()
		self.dbus_obj.set_callback(dbus_device_fill_list)


	def device_item(self, device_data):
		device_group = edje.Edje(self.ecanvas)
		device_group.file_set(self.edje_file, "device_item")
		device_group.part_text_set("device_name", device_data[1])
		device_group.move(self.coord[0], self.coord[1])
		self.coord = (self.coord[0], self.coord[1] + 40)
		device_group.signal_callback_add("mouse,clicked,*", "*",
						 self.on_mouse_clicked)
		device_group.show()


	def on_mouse_clicked(self, edje_obj, emission, source, data=None):
		global prot_obj
		print "> on_mouse_clicked: " + source
		device_name = edje_obj.part_text_get("device_name")
		print 'name = ' + device_name + '\taddress = ' + devices[device_name]

		bt_socket.close()
		bt_socket.connect(devices[device_name])

		if prot_obj == None:
			prot_obj = protocol.protocol(WIDTH_DFL, HEIGHT_DFL)

		prot_obj.comm_channel(bt_socket)
		prot_obj.connect()
		control = controller.Controller(canvas, prot_obj)



class AmoraView(object):
	def __init__(self, ecanvas):
		self.ee = ecanvas.ee

		if len(sys.argv) > 1:
			self.edje_file = sys.argv[1]
		else:
			# do not hardcode edje file path
			self.edje_file = APP_DATADIR + os.path.basename(sys.argv[0]) + ".edj"

		try:
			self.main_group = edje.Edje(self.ee.evas,
						    file=self.edje_file,
						    group="main")
		except edje.EdjeLoadError, e:
			raise SystemExit("Error loading %s (%s)" %
					 (self.edje_file, e))

		self.main_group.size = self.ee.evas.size
		self.ee.data["main"] = self.main_group

		self.main_group.show()
		self.main_group.focus = True

		self.main_group.signal_callback_add("mouse,down,*", "*",
						    self.on_mouse_down)
		self.main_group.signal_callback_add("mouse,up,*", "*",
						    self.on_mouse_up)
		self.main_group.signal_callback_add("mouse,clicked,*", "*",
						    self.on_mouse_clicked)
		self.main_group.signal_callback_add("scan_devices", "*",
						    self.on_devices_scan)

		self.main_group.on_key_down_add(self.on_key_down)


	def on_key_down(self, obj, event):
		if event.keyname == "Escape":
			ecore.main_loop_quit()
		elif event.keyname == "F6":
			self.ee.fullscreen = not self.ee.fullscreen


	def on_mouse_down(self, edje_obj, emission, source, data=None):
		print "> Mouse Down: " + source


	def on_mouse_up(self, edje_obj, emission, source, data=None):
		print "< Mouse Up:   " + source


	def on_mouse_clicked(self, edje_obj, emission, source, data=None):
		print "! Mouse Clicked: " + source

		if source == "exit_button":
			bt_socket.close()
			ecore.main_loop_quit()


	def on_devices_scan(self, edje_obj, emission, source, data=None):
		print "@ Scanning devices";
		global device_list

		x, y, w, h = self.main_group.part_geometry_get("device_list")
		coord = (x, y)
		device_list = AmoraDeviceList(self.ee.evas, self.edje_file,
					      coord)
		device_list.dbus_obj.discover()


	def swallow_item(self, name, devices):
		print u'Swallow the fucker'
		self.main_group.part_swallow(name, devices);



class AmoraCanvas(object):
	def  __init__(self, size, fullscreen):

		# checks if 16bits support on X11 is enabled
		if ecore.evas.engine_type_supported_get("software_x11_16") and \
			'-x11' not in sys.argv:
			engine = ecore.evas.SoftwareX11_16
			print u'Evas engine: x11-16'
		else:
			engine = ecore.evas.SoftwareX11
			print u'Evas engine: x11'

		self.ee = engine(w=size[0], h=size[1])

		if (fullscreen):
			self.ee.fullscreen = True

		self.ee.callback_resize = self.on_resize
		self.ee.size = size;
		self.ee.title = APP_TITLE
		self.ee.name_class = APP_WM_INFO

		self.ee.callback_delete_request = self.on_delete_request
		self.ee.callback_resize = self.on_resize

		self.ee.show()


	def on_resize(self, ee):
		x, y, w, h = ee.evas.viewport
		size = (w, h)
		for key in ee.data.keys():
			ee.data[key].size = size


	def on_delete_request(self, ee):
		ecore.main_loop_quit()


if  __name__  == "__main__":
	from optparse import OptionParser

	def parse_size(option, opt, value, parser):
		global WIDTH_DFL, HEIGHT_DFL
		try:
			w, h = value.split("x")
			w = int(w)
			h = int(h)
			print 'w = ' + str(w) + '\th= ' + str(h)
			print str(WIDTH_DFL) + '\t' + str(HEIGHT_DFL)
			WIDTH_DFL = w
			HEIGHT_DFL = h
			print str(WIDTH_DFL) + '\t' + str(HEIGHT_DFL)
		except Exception, e:
			raise optparse.OptionValueError("Invalid option: %s" %
							option)
		parser.values.size = (w, h)

	opt = OptionParser(usage="usage: %prog [options]")
	opt.add_option("-s", "--size", type="string", metavar="WxH",
					action="callback", callback=parse_size,
					default=(WIDTH_DFL, HEIGHT_DFL),
					help="Show application in window WxH,\
					default=%default")

	opt.add_option("-f", "--fps", type="int", default=FPS_DFL,
					help="Frames per second, \
					default=%default")

	opt.add_option("-n", "--no-fullscreen", action="store_true",
					help="Show application in fullscreen")

	options, args = opt.parse_args()

	edje.frametime_set(1.0/options.fps)

	canvas = AmoraCanvas(size=options.size, fullscreen=not
			     options.no_fullscreen)

	view = AmoraView(canvas)

	ecore.main_loop_begin();

